import pymysql, redis
# 将字典中的字节串转为字符串
def to_dict(user_dict):
    new_dict = {}
    for item in user_dict.items():
        key = item[0].decode('utf-8')
        value = item[1].decode('utf-8')
        # 添加到新字典
        new_dict[key] = value
    return new_dict
# 编写数据库同步类，完成对数据库的增删改查
class DataSync:
    # 构造方法中，完成初始化操作
    def __init__(self):
        # 创建mysql数据库的连接，保存到一个属性中
        try:
            self.conn = pymysql.connect(
                host='192.168.88.128',
                port=3306,
                user='root',
                password='123456',
                db='tedu_test',
                charset='utf8'
            )
            self.cur = self.conn.cursor() # 创建游标
        except Exception as e:
            print('连接失败，失败原因：', e)
            # 退出程序
            exit(1)
        # 创建redis连接
        try:
            self.r = redis.Redis(host='localhost',port=6379,db=0)
        except Exception as e:
            print('redis连接失败，错误原因：', e)
            exit(2)
    # 数据查询，传递ID
    def get_data(self, stu_id):
        # 设置在redis中的名称
        hash_name = f'stu_{stu_id}'
        # 先查询redis数据
        result = self.r.hgetall(hash_name)
        # print(result)
        # 如果查询到了，直接返回redis查询的数据，否则往后到mysql查询
        if len(result) > 0:
            # 一旦访问到了redis中的数据，重新设置有效期
            self.r.expire(hash_name, 600)
            print('select by redis')
            # 将结果中的字节串转为字符串再返回
            return to_dict(result)
        # 执行sql命令，查询出编号对应的数据
        self.cur.execute(f'select * from tedu_student where stu_id={stu_id}')
        # (1001, 'zs', datetime.date(1990, 12, 15), '13344445555')
        row = self.cur.fetchone()
        # 如果不存在
        if not row:
            return '该用户不存在'
        # 将元组数据改为字典格式 {'stu_id'：x,'stu_name':x,..}
        stu_dict = {
            'stu_id': row[0],
            'stu_name': row[1],
            'stu_birth': str(row[2]),
            'stu_phone': row[3]
        }

        # 将查询的数据同步一份到redis
        for item in stu_dict.items():
            self.r.hset(hash_name, item[0], item[1])
        # 设置有效期为10分钟
        self.r.expire(hash_name, 600)
        # 将查询的数据返回
        print('select by mysql')
        return stu_dict
    # 数据插入（将数据插入到mysql）

    # 数据删除(删除mysql数据，如果redis存在，同时也删除)
    def delete_data(self, stu_id):
        self.cur.execute(f'delete from tedu_student where stu_id={stu_id}')
        # 提交事务
        self.conn.commit()
        # 删除redis
        # 设置hash名称
        hash_name = f'stu_{stu_id}'
        result = self.r.hgetall(hash_name)
        # 如果存在
        if len(result) > 0:
            self.r.delete(hash_name)
        return '数据删除成功'
    # 数据更改（更新mysql数据，如果redis存在，同时也删除）



if __name__ == '__main__':
    d1 = DataSync()
    # 删除数据
    # d1.delete_data(1002)
    # 查询数据
    print(d1.get_data(1002))